#pragma once

#include <libs/klibc.h>
#include <mm/bitmap.h>
#include <mm/hhdm.h>
#include <mm/heap.h>
#include <mm/page_table_flags.h>
#include <arch/arch.h>
#include <limine.h>

// Limine内存映射请求的外部声明
extern volatile struct limine_memmap_request memmap_request;

#define MAX_USABLE_REGIONS_COUNT 128

// #define DEFAULT_PAGE_SIZE 4096

typedef struct
{
    Bitmap bitmap;
    size_t origin_frames;
    size_t usable_frames;
} FrameAllocator;

extern FrameAllocator frame_allocator;

void frame_init();

void free_frames(uint64_t addr, uint64_t size);
uint64_t alloc_frames(size_t count);

void map_page_range(uint64_t *pml4, uint64_t vaddr, uint64_t paddr, uint64_t size, uint64_t flags);
void unmap_page_range(uint64_t *pml4, uint64_t vaddr, uint64_t size);

static inline void *alloc_frames_bytes(uint64_t bytes)
{
    return phys_to_virt((void *)alloc_frames((bytes + DEFAULT_PAGE_SIZE - 1) / DEFAULT_PAGE_SIZE));
}

static inline void free_frames_bytes(void *ptr, uint64_t bytes)
{
    free_frames(virt_to_phys((uint64_t)ptr), (bytes + DEFAULT_PAGE_SIZE - 1) / DEFAULT_PAGE_SIZE);
}